home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / linux / cpumask.h < prev    next >
C/C++ Source or Header  |  2005-10-13  |  13KB  |  381 lines

  1. #ifndef __LINUX_CPUMASK_H
  2. #define __LINUX_CPUMASK_H
  3.  
  4. #ifdef __KERNEL__
  5.  
  6. /*
  7.  * Cpumasks provide a bitmap suitable for representing the
  8.  * set of CPU's in a system, one bit position per CPU number.
  9.  *
  10.  * See detailed comments in the file linux/bitmap.h describing the
  11.  * data type on which these cpumasks are based.
  12.  *
  13.  * For details of cpumask_scnprintf() and cpumask_parse(),
  14.  * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
  15.  *
  16.  * The available cpumask operations are:
  17.  *
  18.  * void cpu_set(cpu, mask)        turn on bit 'cpu' in mask
  19.  * void cpu_clear(cpu, mask)        turn off bit 'cpu' in mask
  20.  * void cpus_setall(mask)        set all bits
  21.  * void cpus_clear(mask)        clear all bits
  22.  * int cpu_isset(cpu, mask)        true iff bit 'cpu' set in mask
  23.  * int cpu_test_and_set(cpu, mask)    test and set bit 'cpu' in mask
  24.  *
  25.  * void cpus_and(dst, src1, src2)    dst = src1 & src2  [intersection]
  26.  * void cpus_or(dst, src1, src2)    dst = src1 | src2  [union]
  27.  * void cpus_xor(dst, src1, src2)    dst = src1 ^ src2
  28.  * void cpus_andnot(dst, src1, src2)    dst = src1 & ~src2
  29.  * void cpus_complement(dst, src)    dst = ~src
  30.  *
  31.  * int cpus_equal(mask1, mask2)        Does mask1 == mask2?
  32.  * int cpus_intersects(mask1, mask2)    Do mask1 and mask2 intersect?
  33.  * int cpus_subset(mask1, mask2)    Is mask1 a subset of mask2?
  34.  * int cpus_empty(mask)            Is mask empty (no bits sets)?
  35.  * int cpus_full(mask)            Is mask full (all bits sets)?
  36.  * int cpus_weight(mask)        Hamming weigh - number of set bits
  37.  *
  38.  * void cpus_shift_right(dst, src, n)    Shift right
  39.  * void cpus_shift_left(dst, src, n)    Shift left
  40.  *
  41.  * int first_cpu(mask)            Number lowest set bit, or NR_CPUS
  42.  * int next_cpu(cpu, mask)        Next cpu past 'cpu', or NR_CPUS
  43.  *
  44.  * cpumask_t cpumask_of_cpu(cpu)    Return cpumask with bit 'cpu' set
  45.  * CPU_MASK_ALL                Initializer - all bits set
  46.  * CPU_MASK_NONE            Initializer - no bits set
  47.  * unsigned long *cpus_addr(mask)    Array of unsigned long's in mask
  48.  *
  49.  * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing
  50.  * int cpumask_parse(ubuf, ulen, mask)    Parse ascii string as cpumask
  51.  *
  52.  * for_each_cpu_mask(cpu, mask)        for-loop cpu over mask
  53.  *
  54.  * int num_online_cpus()        Number of online CPUs
  55.  * int num_possible_cpus()        Number of all possible CPUs
  56.  * int num_present_cpus()        Number of present CPUs
  57.  *
  58.  * int cpu_online(cpu)            Is some cpu online?
  59.  * int cpu_possible(cpu)        Is some cpu possible?
  60.  * int cpu_present(cpu)            Is some cpu present (can schedule)?
  61.  *
  62.  * int any_online_cpu(mask)        First online cpu in mask
  63.  *
  64.  * for_each_cpu(cpu)            for-loop cpu over cpu_possible_map
  65.  * for_each_online_cpu(cpu)        for-loop cpu over cpu_online_map
  66.  * for_each_present_cpu(cpu)        for-loop cpu over cpu_present_map
  67.  *
  68.  * Subtlety:
  69.  * 1) The 'type-checked' form of cpu_isset() causes gcc (3.3.2, anyway)
  70.  *    to generate slightly worse code.  Note for example the additional
  71.  *    40 lines of assembly code compiling the "for each possible cpu"
  72.  *    loops buried in the disk_stat_read() macros calls when compiling
  73.  *    drivers/block/genhd.c (arch i386, CONFIG_SMP=y).  So use a simple
  74.  *    one-line #define for cpu_isset(), instead of wrapping an inline
  75.  *    inside a macro, the way we do the other calls.
  76.  */
  77.  
  78. #include <linux/kernel.h>
  79. #include <linux/threads.h>
  80. #include <linux/bitmap.h>
  81. #include <asm/bug.h>
  82.  
  83. typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
  84. extern cpumask_t _unused_cpumask_arg_;
  85.  
  86. #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
  87. static inline void __cpu_set(int cpu, volatile cpumask_t *dstp)
  88. {
  89.     set_bit(cpu, dstp->bits);
  90. }
  91.  
  92. #define cpu_clear(cpu, dst) __cpu_clear((cpu), &(dst))
  93. static inline void __cpu_clear(int cpu, volatile cpumask_t *dstp)
  94. {
  95.     clear_bit(cpu, dstp->bits);
  96. }
  97.  
  98. #define cpus_setall(dst) __cpus_setall(&(dst), NR_CPUS)
  99. static inline void __cpus_setall(cpumask_t *dstp, int nbits)
  100. {
  101.     bitmap_fill(dstp->bits, nbits);
  102. }
  103.  
  104. #define cpus_clear(dst) __cpus_clear(&(dst), NR_CPUS)
  105. static inline void __cpus_clear(cpumask_t *dstp, int nbits)
  106. {
  107.     bitmap_zero(dstp->bits, nbits);
  108. }
  109.  
  110. /* No static inline type checking - see Subtlety (1) above. */
  111. #define cpu_isset(cpu, cpumask) test_bit((cpu), (cpumask).bits)
  112.  
  113. #define cpu_test_and_set(cpu, cpumask) __cpu_test_and_set((cpu), &(cpumask))
  114. static inline int __cpu_test_and_set(int cpu, cpumask_t *addr)
  115. {
  116.     return test_and_set_bit(cpu, addr->bits);
  117. }
  118.  
  119. #define cpus_and(dst, src1, src2) __cpus_and(&(dst), &(src1), &(src2), NR_CPUS)
  120. static inline void __cpus_and(cpumask_t *dstp, const cpumask_t *src1p,
  121.                     const cpumask_t *src2p, int nbits)
  122. {
  123.     bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits);
  124. }
  125.  
  126. #define cpus_or(dst, src1, src2) __cpus_or(&(dst), &(src1), &(src2), NR_CPUS)
  127. static inline void __cpus_or(cpumask_t *dstp, const cpumask_t *src1p,
  128.                     const cpumask_t *src2p, int nbits)
  129. {
  130.     bitmap_or(dstp->bits, src1p->bits, src2p->bits, nbits);
  131. }
  132.  
  133. #define cpus_xor(dst, src1, src2) __cpus_xor(&(dst), &(src1), &(src2), NR_CPUS)
  134. static inline void __cpus_xor(cpumask_t *dstp, const cpumask_t *src1p,
  135.                     const cpumask_t *src2p, int nbits)
  136. {
  137.     bitmap_xor(dstp->bits, src1p->bits, src2p->bits, nbits);
  138. }
  139.  
  140. #define cpus_andnot(dst, src1, src2) \
  141.                 __cpus_andnot(&(dst), &(src1), &(src2), NR_CPUS)
  142. static inline void __cpus_andnot(cpumask_t *dstp, const cpumask_t *src1p,
  143.                     const cpumask_t *src2p, int nbits)
  144. {
  145.     bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits);
  146. }
  147.  
  148. #define cpus_complement(dst, src) __cpus_complement(&(dst), &(src), NR_CPUS)
  149. static inline void __cpus_complement(cpumask_t *dstp,
  150.                     const cpumask_t *srcp, int nbits)
  151. {
  152.     bitmap_complement(dstp->bits, srcp->bits, nbits);
  153. }
  154.  
  155. #define cpus_equal(src1, src2) __cpus_equal(&(src1), &(src2), NR_CPUS)
  156. static inline int __cpus_equal(const cpumask_t *src1p,
  157.                     const cpumask_t *src2p, int nbits)
  158. {
  159.     return bitmap_equal(src1p->bits, src2p->bits, nbits);
  160. }
  161.  
  162. #define cpus_intersects(src1, src2) __cpus_intersects(&(src1), &(src2), NR_CPUS)
  163. static inline int __cpus_intersects(const cpumask_t *src1p,
  164.                     const cpumask_t *src2p, int nbits)
  165. {
  166.     return bitmap_intersects(src1p->bits, src2p->bits, nbits);
  167. }
  168.  
  169. #define cpus_subset(src1, src2) __cpus_subset(&(src1), &(src2), NR_CPUS)
  170. static inline int __cpus_subset(const cpumask_t *src1p,
  171.                     const cpumask_t *src2p, int nbits)
  172. {
  173.     return bitmap_subset(src1p->bits, src2p->bits, nbits);
  174. }
  175.  
  176. #define cpus_empty(src) __cpus_empty(&(src), NR_CPUS)
  177. static inline int __cpus_empty(const cpumask_t *srcp, int nbits)
  178. {
  179.     return bitmap_empty(srcp->bits, nbits);
  180. }
  181.  
  182. #define cpus_full(cpumask) __cpus_full(&(cpumask), NR_CPUS)
  183. static inline int __cpus_full(const cpumask_t *srcp, int nbits)
  184. {
  185.     return bitmap_full(srcp->bits, nbits);
  186. }
  187.  
  188. #define cpus_weight(cpumask) __cpus_weight(&(cpumask), NR_CPUS)
  189. static inline int __cpus_weight(const cpumask_t *srcp, int nbits)
  190. {
  191.     return bitmap_weight(srcp->bits, nbits);
  192. }
  193.  
  194. #define cpus_shift_right(dst, src, n) \
  195.             __cpus_shift_right(&(dst), &(src), (n), NR_CPUS)
  196. static inline void __cpus_shift_right(cpumask_t *dstp,
  197.                     const cpumask_t *srcp, int n, int nbits)
  198. {
  199.     bitmap_shift_right(dstp->bits, srcp->bits, n, nbits);
  200. }
  201.  
  202. #define cpus_shift_left(dst, src, n) \
  203.             __cpus_shift_left(&(dst), &(src), (n), NR_CPUS)
  204. static inline void __cpus_shift_left(cpumask_t *dstp,
  205.                     const cpumask_t *srcp, int n, int nbits)
  206. {
  207.     bitmap_shift_left(dstp->bits, srcp->bits, n, nbits);
  208. }
  209.  
  210. #define first_cpu(src) __first_cpu(&(src), NR_CPUS)
  211. static inline int __first_cpu(const cpumask_t *srcp, int nbits)
  212. {
  213.     return min_t(int, nbits, find_first_bit(srcp->bits, nbits));
  214. }
  215.  
  216. #define next_cpu(n, src) __next_cpu((n), &(src), NR_CPUS)
  217. static inline int __next_cpu(int n, const cpumask_t *srcp, int nbits)
  218. {
  219.     return min_t(int, nbits, find_next_bit(srcp->bits, nbits, n+1));
  220. }
  221.  
  222. #define cpumask_of_cpu(cpu)                        \
  223. ({                                    \
  224.     typeof(_unused_cpumask_arg_) m;                    \
  225.     if (sizeof(m) == sizeof(unsigned long)) {            \
  226.         m.bits[0] = 1UL<<(cpu);                    \
  227.     } else {                            \
  228.         cpus_clear(m);                        \
  229.         cpu_set((cpu), m);                    \
  230.     }                                \
  231.     m;                                \
  232. })
  233.  
  234. #define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS)
  235.  
  236. #if NR_CPUS <= BITS_PER_LONG
  237.  
  238. #define CPU_MASK_ALL                            \
  239. (cpumask_t) { {                                \
  240.     [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD            \
  241. } }
  242.  
  243. #else
  244.  
  245. #define CPU_MASK_ALL                            \
  246. (cpumask_t) { {                                \
  247.     [0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL,            \
  248.     [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD            \
  249. } }
  250.  
  251. #endif
  252.  
  253. #define CPU_MASK_NONE                            \
  254. (cpumask_t) { {                                \
  255.     [0 ... BITS_TO_LONGS(NR_CPUS)-1] =  0UL                \
  256. } }
  257.  
  258. #define CPU_MASK_CPU0                            \
  259. (cpumask_t) { {                                \
  260.     [0] =  1UL                            \
  261. } }
  262.  
  263. #define cpus_addr(src) ((src).bits)
  264.  
  265. #define cpumask_scnprintf(buf, len, src) \
  266.             __cpumask_scnprintf((buf), (len), &(src), NR_CPUS)
  267. static inline int __cpumask_scnprintf(char *buf, int len,
  268.                     const cpumask_t *srcp, int nbits)
  269. {
  270.     return bitmap_scnprintf(buf, len, srcp->bits, nbits);
  271. }
  272.  
  273. #define cpumask_parse(ubuf, ulen, src) \
  274.             __cpumask_parse((ubuf), (ulen), &(src), NR_CPUS)
  275. static inline int __cpumask_parse(const char __user *buf, int len,
  276.                     cpumask_t *dstp, int nbits)
  277. {
  278.     return bitmap_parse(buf, len, dstp->bits, nbits);
  279. }
  280.  
  281. #if NR_CPUS > 1
  282. #define for_each_cpu_mask(cpu, mask)        \
  283.     for ((cpu) = first_cpu(mask);        \
  284.         (cpu) < NR_CPUS;        \
  285.         (cpu) = next_cpu((cpu), (mask)))
  286. #else /* NR_CPUS == 1 */
  287. #define for_each_cpu_mask(cpu, mask) for ((cpu) = 0; (cpu) < 1; (cpu)++)
  288. #endif /* NR_CPUS */
  289.  
  290. /*
  291.  * The following particular system cpumasks and operations manage
  292.  * possible, present and online cpus.  Each of them is a fixed size
  293.  * bitmap of size NR_CPUS.
  294.  *
  295.  *  #ifdef CONFIG_HOTPLUG_CPU
  296.  *     cpu_possible_map - all NR_CPUS bits set
  297.  *     cpu_present_map  - has bit 'cpu' set iff cpu is populated
  298.  *     cpu_online_map   - has bit 'cpu' set iff cpu available to scheduler
  299.  *  #else
  300.  *     cpu_possible_map - has bit 'cpu' set iff cpu is populated
  301.  *     cpu_present_map  - copy of cpu_possible_map
  302.  *     cpu_online_map   - has bit 'cpu' set iff cpu available to scheduler
  303.  *  #endif
  304.  *
  305.  *  In either case, NR_CPUS is fixed at compile time, as the static
  306.  *  size of these bitmaps.  The cpu_possible_map is fixed at boot
  307.  *  time, as the set of CPU id's that it is possible might ever
  308.  *  be plugged in at anytime during the life of that system boot.
  309.  *  The cpu_present_map is dynamic(*), representing which CPUs
  310.  *  are currently plugged in.  And cpu_online_map is the dynamic
  311.  *  subset of cpu_present_map, indicating those CPUs available
  312.  *  for scheduling.
  313.  *
  314.  *  If HOTPLUG is enabled, then cpu_possible_map is forced to have
  315.  *  all NR_CPUS bits set, otherwise it is just the set of CPUs that
  316.  *  ACPI reports present at boot.
  317.  *
  318.  *  If HOTPLUG is enabled, then cpu_present_map varies dynamically,
  319.  *  depending on what ACPI reports as currently plugged in, otherwise
  320.  *  cpu_present_map is just a copy of cpu_possible_map.
  321.  *
  322.  *  (*) Well, cpu_present_map is dynamic in the hotplug case.  If not
  323.  *      hotplug, it's a copy of cpu_possible_map, hence fixed at boot.
  324.  *
  325.  * Subtleties:
  326.  * 1) UP arch's (NR_CPUS == 1, CONFIG_SMP not defined) hardcode
  327.  *    assumption that their single CPU is online.  The UP
  328.  *    cpu_{online,possible,present}_maps are placebos.  Changing them
  329.  *    will have no useful affect on the following num_*_cpus()
  330.  *    and cpu_*() macros in the UP case.  This ugliness is a UP
  331.  *    optimization - don't waste any instructions or memory references
  332.  *    asking if you're online or how many CPUs there are if there is
  333.  *    only one CPU.
  334.  * 2) Most SMP arch's #define some of these maps to be some
  335.  *    other map specific to that arch.  Therefore, the following
  336.  *    must be #define macros, not inlines.  To see why, examine
  337.  *    the assembly code produced by the following.  Note that
  338.  *    set1() writes phys_x_map, but set2() writes x_map:
  339.  *        int x_map, phys_x_map;
  340.  *        #define set1(a) x_map = a
  341.  *        inline void set2(int a) { x_map = a; }
  342.  *        #define x_map phys_x_map
  343.  *        main(){ set1(3); set2(5); }
  344.  */
  345.  
  346. extern cpumask_t cpu_possible_map;
  347. extern cpumask_t cpu_online_map;
  348. extern cpumask_t cpu_present_map;
  349.  
  350. #if NR_CPUS > 1
  351. #define num_online_cpus()    cpus_weight(cpu_online_map)
  352. #define num_possible_cpus()    cpus_weight(cpu_possible_map)
  353. #define num_present_cpus()    cpus_weight(cpu_present_map)
  354. #define cpu_online(cpu)        cpu_isset((cpu), cpu_online_map)
  355. #define cpu_possible(cpu)    cpu_isset((cpu), cpu_possible_map)
  356. #define cpu_present(cpu)    cpu_isset((cpu), cpu_present_map)
  357. #else
  358. #define num_online_cpus()    1
  359. #define num_possible_cpus()    1
  360. #define num_present_cpus()    1
  361. #define cpu_online(cpu)        ((cpu) == 0)
  362. #define cpu_possible(cpu)    ((cpu) == 0)
  363. #define cpu_present(cpu)    ((cpu) == 0)
  364. #endif
  365.  
  366. #define any_online_cpu(mask)            \
  367. ({                        \
  368.     int cpu;                \
  369.     for_each_cpu_mask(cpu, (mask))        \
  370.         if (cpu_online(cpu))        \
  371.             break;            \
  372.     cpu;                    \
  373. })
  374.  
  375. #define for_each_cpu(cpu)      for_each_cpu_mask((cpu), cpu_possible_map)
  376. #define for_each_online_cpu(cpu)  for_each_cpu_mask((cpu), cpu_online_map)
  377. #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map)
  378.  
  379. #endif /* __KERNEL__ */
  380. #endif /* __LINUX_CPUMASK_H */
  381.